package cn.bluethink.eguan.core.service;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.pagehelper.PageHelper;

import cn.bluethink.eguan.core.entity.EgBtsEntity;
import cn.bluethink.eguan.core.mapper.EgBtsMapper;
import cn.bluethink.eguan.filter.BtsFilter;
import cn.bluethink.eguan.model.core.EgBts;
import cn.bluethink.eguan.model.core.EgBtsStatus;
import cn.bluethink.eguan.model.core.EgConfigInfo;
import cn.bluethink.eguan.model.core.EgOType;
import cn.bluethink.eguan.model.core.EgObject;
import cn.bluethink.eguan.model.core.EgUser;
import cn.bluethink.eguan.result.PageInfo;
import cn.bluethink.eguan.utils.IdMakerUtils;

/**
 * 金币流通记录业务层
 * 
 * @author 苏州中科蓝迪公司所有(c)2016-2021
 * @version 0.3.0
 * @brief 驿馆+产品
 * @note 修订历史： 1.wanglei于2018/12/06设计并构建初始版本v0.3.0
 */
@Service
public class EgBtsService {

    @Autowired
    private EgBtsMapper btsMapper;

    @Autowired
    private EgUserService userService;

    @Autowired
    private EgFactionService factionService;

    @Autowired
    private EgConfigInfo configInfo;

    private IdMakerUtils idMakerUtil = new IdMakerUtils();

    /**
     * 创建金币流通记录(不暴露接口)
     * 
     * @param oAcount
     *            来源账户（出钱）
     * @param obj
     *            交易对象
     * @param price
     *            交易价格
     * @param number
     *            交易数量 （只针对商品）
     * @param dAcount
     *            目的账户（进钱）
     * @return
     * @throws Exception
     */
    @Transactional(transactionManager = "eguanTransactionManager", rollbackFor = Exception.class)
    public EgBts create(Long oAcount, EgObject obj, Integer price, Integer number, Long dAcount) throws Exception {
        // 创建实体
        EgBtsEntity entity = new EgBtsEntity(oAcount, obj, price, number, dAcount);
        entity.setId(idMakerUtil.nextId());
        int insertCount = btsMapper.insertSelective(entity);
        return insertCount > 0 ? entity.creatEgBts() : null;
    }

    /**
     * 过滤查询金币流通记录
     * 
     * @param filter
     * @return
     * @throws Exception
     */
    public PageInfo<EgBts> query(BtsFilter filter) throws Exception {
        Integer pageNum = filter.getPageNum() == null ? 1 : filter.getPageNum();
        Integer pageSize = filter.getPageSize() == null ? 20 : filter.getPageSize();
        Boolean addOrReduce = filter.getAddOrReduce();
        Long acountId = getAcount(filter);
        // 构造查询条件
        String whereSql = buildQuerySql(filter, acountId);
        // 返回结果
        List<EgBts> result = new ArrayList<>();
        List<EgBtsEntity> entities = new ArrayList<>();
        // 判断whereSql不为空，根据条件查询
        if (StringUtils.isNotBlank(whereSql)) {
            // 分页
            PageHelper.startPage(pageNum, pageSize);
            entities = btsMapper.query(whereSql);
        }
        PageInfo<EgBtsEntity> oldPageInfo = new PageInfo<>(entities);
        result = getRecords(entities, acountId, addOrReduce);
        return new PageInfo<>(result, oldPageInfo);

    }

    /**
     * 根据过滤条件构建查询条件
     * 
     * @param filter
     * @param acountId
     * @return
     * @throws Exception
     */
    private String buildQuerySql(BtsFilter filter, Long acountId) throws Exception {
        String whereSql = "";
        List<String> whereSqlList = new ArrayList<>();
        whereSqlList.add(" 1 = 1");
        // 默认null查询所有，为true查询收入，为false查询支出
        Boolean addOrReduce = filter.getAddOrReduce();
        if (addOrReduce != null) {
            if (addOrReduce) {
                whereSqlList.add(" B.d_a = " + acountId);
            } else {
                whereSqlList.add(" B.o_a = " + acountId);
            }
        } else {
            whereSqlList.add(" B.d_a = " + acountId + " OR B.o_a = " + acountId);
        }
        // 设置查询条件AND连接符
        if (whereSqlList.size() > 0) {
            whereSql += String.join(" AND ", whereSqlList);
        }
        // 排序规则(创建时间倒序)
        whereSql += " ORDER BY B.ctime DESC";
        return whereSql;
    }

    /**
     * 根据传入的对象获取相应的账户ID
     * 
     * @param filter
     * @return
     * @throws Exception
     */
    private Long getAcount(BtsFilter filter) throws Exception {
        // 声明过滤条件
        Long id = filter.getId() == null ? 0 : filter.getId();
        Boolean buid = filter.getBuid() == null ? false : filter.getBuid();
        Integer otype = filter.getOtype() == null ? EgOType.JIANGHU : filter.getOtype();
        // 如果是查询江湖中
        if (id == 0 && otype.equals(EgOType.JIANGHU) && !buid) {
            return configInfo.getAcountId();
        }
        if (id > 0 && otype != null && !buid) {
            // 如果是查询某个用户
            if (otype.equals(EgOType.USER)) {
                EgUser user = userService.getUser(id, false);
                if (user == null) {
                    return null;
                }
                return user.getAcount().getId();
            }
            // 如果是查询某个门派
            if (otype.equals(EgOType.FACTION)) {
                Long fAcount = factionService.getAcountByFid(id);
                if (fAcount == 0) {
                    return null;
                }
                return fAcount;
            }
        }
        return null;
    }

    /**
     * 返回的金币流通记录列表（是支出还是收入或者不增不减）
     * 
     * @param entities
     * @param acountId
     * @param addOrReduce
     * @return
     * @throws Exception
     */
    private List<EgBts> getRecords(List<EgBtsEntity> entities, Long acountId, Boolean addOrReduce) throws Exception {
        List<EgBts> result = new ArrayList<>();
        if (entities == null || entities.size() <= 0) {
            return new ArrayList<>();
        }
        for (EgBtsEntity entity : entities) {
            EgBts bts = entity.creatEgBts();
            // 查询支出
            if (addOrReduce != null && !addOrReduce) {
                bts.setStatus(EgBtsStatus.STATUS_REDUCE);
            }
            // 查询收入
            if (addOrReduce != null && addOrReduce) {
                bts.setStatus(EgBtsStatus.STATUS_ADD);
            }
            // 查询所有：支出，收入，不增不减
            if (addOrReduce == null) {
                Boolean dA = entity.getdA().equals(acountId);
                Boolean oA = entity.getoA().equals(acountId);
                if (dA && oA) {
                    bts.setStatus(EgBtsStatus.STATUS_NO_CHANGE);
                }
                if (oA && !dA) {
                    bts.setStatus(EgBtsStatus.STATUS_REDUCE);
                }
                if (dA && !oA) {
                    bts.setStatus(EgBtsStatus.STATUS_ADD);
                }
            }
            result.add(bts);
        }
        return result;
    }
}
